using System;
using System.Collections.Generic;
using System.Text;

using System.Data;
using System.Data.OleDb;

namespace SqlToolkit.Oracle.Schema
{
    public class SqlDbTableFieldBase : SqlDbFieldBase
    {
        #region DATA_TYPE
        protected string data_type = string.Empty;
        public string DataType
        {
            get { return data_type; }
            //set{if(value != data_type;}
        }
        #endregion
        #region IS_NULLABLE / NULLABLE
        protected string is_nullable = string.Empty;
        public string IsNullable
        {
            get { return is_nullable; }
            //set{if(value != is_nullable) is_nullable = value;}
        }
        #endregion
        #region ORDINAL_POSITION / COLUMN_ID
        protected decimal ordinal_position = -1;
        public decimal OridinalPosition
        {
            get { return ordinal_position; }
            //set{if(value != oridnal_position) value = oridinal_position;}
        }
        #endregion
        #region COLUMN_DEFAULT / DATA_DEFAULT
        protected string column_default = string.Empty;
        public string ColumnDefault
        {
            get { return column_default; }
            //set{if(value != column_default) column_default = value;}
        }
        #endregion
        #region NUMERIC_PRECISION / DATA_PRECISION
        protected int numeric_precision = -1;
        public int NumericPrecision
        {
            get { return numeric_precision; }
            //set{if(value != numeric_precision) numeric_precision = value;}
        }
        #endregion
        #region CHARACTER_MAXIMUM_LENGTH / CHAR_LENGTH
        protected double charachter_maximum_length = -1;
        public double CharacterMaximumLength
        {
            get { return charachter_maximum_length; }
            //set{if(value != charachter_maximum_length) charachter_maximum_length = value;}
        }
        #endregion
        #region DATA_LENGTH
        protected int data_length = 0;
        public int DataLength
        {
            get { return data_length; }
        }
        #endregion
        #region DATA_PRECISION
        protected int data_precision = 0;
        public int DataPrecision
        {
            get { return data_precision; }
        }
         #endregion
        #region Type Info (Note: may need to map AdoType info as well)
        /// <summary>
        /// Provide quick access to the Oracle.DataAccess.OracleSqlToolsType of this Column.
        /// </summary>
        public System.Data.DbType OracleDataType
        {
            get
            {
                switch (this.data_type.ToUpper())
                {
                    case "BLOB":
                        return System.Data.DbType.Binary;
                    case "CHAR":
                        return System.Data.DbType.String;
                    case "CLOB":
                        return System.Data.DbType.String;
                    case "DATE":
                        return System.Data.DbType.DateTime;
                    case "FLOAT":
                        return System.Data.DbType.Single;
                    case "INTEGER":
                        return System.Data.DbType.Int32;
                    case "NUMBER":
                        return System.Data.DbType.Int32;
                    case "TIMESTAMP":
                        return System.Data.DbType.DateTime;
                    case "VARCHAR2":
                        return System.Data.DbType.String;
                    default:
                        return System.Data.DbType.String;
                }
            }
        }

        public string ColumnBindVariableName()
        {
            return ColumnBindVariableName(this.ColumnName);
        }

        public string SqlValueExpression(string val)
        {
            string ret = string.Empty;

            if ((null != this.DataType && DataType != string.Empty) && (null != val && val != string.Empty))
            {
                switch (this.DataType)
                {
                    case "FLOAT":
                        ret = " CAST('" + val + "' As " + this.DataType + "(" + this.DataLength.ToString() + "," + this.DataPrecision + ")) ";
                        break;
                    case "INTEGER":
                    case "NUMBER":
                    case "UNSIGNED INTEGER":
                        ret = " CAST('" + val + "' As " + this.DataType + "(" + this.DataLength.ToString() + "," + this.DataPrecision + ")) "; break;
                    case "DATE":
                        ret = "TO_DATE('" + val + "', 'DD/MM/YYYY')";
                        break;
                    default:
                        ret = val;
                        break;
                }

            }

            return ret;
        }

        /// <summary>
        /// Determins the correct .net type to be used for this column.
        /// </summary>
        /// <remarks>
        /// This property will throw an error if the type is not a known type.
        /// </remarks>
        public Type ValueType
        {
            get
            {
                switch (this.OracleDataType)
                {
                    case System.Data.DbType.Binary:
                        return typeof(byte[]);
                    case System.Data.DbType.Int32:
                        return typeof(int);
                    case System.Data.DbType.Date:
                        return typeof(DateTime);
                    case System.Data.DbType.Decimal:
                        return typeof(decimal);
                    case System.Data.DbType.DateTime:
                        return typeof(DateTime);
                    case System.Data.DbType.String:
                        return typeof(string);
                    default:
                        return typeof(object);
                }
            }
        }
        #endregion

        public string ColumnNameFriendly()
        {
            return FriendlyName(this.ColumnName);
        }

        public string ColumnBindVariableName(string name)
        {
            StringBuilder ret = new StringBuilder();

            string[] parts = name.Split('_');

            for (int i = 0; i < parts.Length; i++)
            {
                string s = parts[i].ToLower();
                if (i > 0)
                {
                    s = s.Substring(0,1).ToUpper() + s.Substring(1);
                }
                ret.Append(s);
            }

            string retStr = ":p_" + ret.ToString();
            return retStr;
        }

        public string ColumnHeaderName()
        {
            return HeaderName(this.ColumnName);
        }
    }
}
